package com.divemotor.ventarepuestosinternet.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import com.divemotor.ventarepuestosinternet.dao.GrupoDAO;
import com.divemotor.ventarepuestosinternet.model.Grupo;
import com.divemotor.ventarepuestosinternet.model.Imagen;
import com.divemotor.ventarepuestosinternet.model.TipoComponente;
import com.divemotor.ventarepuestosinternet.model.Vehiculo;
import com.divemotor.ventarepuestosinternet.model.VehiculoExtra;
import com.divemotor.ventarepuestosinternet.util.Constantes;


@SuppressWarnings("unchecked")
@Repository(value="grupoDAO")
public class GrupoDAOImpl extends GenericoDAOImpl<Grupo, Integer> implements GrupoDAO, Serializable {

	private static final long serialVersionUID = -7673296888562440185L;

	public GrupoDAOImpl() {
		super();
		setClase(Grupo.class);
	}

	@Override
	public List<Grupo> buscarGrupos(Grupo grupo) {
			
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Grupo.class);
					
			if(!grupo.getCodigo().equals("")){
				criteria.add(Restrictions.like("codigo","%"+grupo.getCodigo()+"%").ignoreCase());
			}
			
			if(!grupo.getNombre().equals("")){
				criteria.add(Restrictions.like("nombre","%"+grupo.getNombre()+"%").ignoreCase());
			}
			
			if(!grupo.getEstado().equals("-")){
				criteria.add(Restrictions.eq("estado", grupo.getEstado()));
			} else {
				criteria.add(Restrictions.not(Restrictions.eq("estado", Constantes.ESTADO_ELIMINADO)));
			}
			
			return criteria.list();
	}

	@Override
	public List<Grupo> listarGruposPorVehiculo(Vehiculo vehiculo, TipoComponente tipoComponente) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Imagen.class, "imagen")
				.createAlias("imagen.modeloFabrica", "modeloFabrica")
				.createAlias("modeloFabrica.listaVehiculoModeloFabrica", "vehiculoModeloFabrica")
				.createAlias("vehiculoModeloFabrica.vehiculo", "vehiculo")				
				.createAlias("imagen.subGrupo", "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.setProjection(Projections.projectionList().add(Projections.distinct(Projections.property("subGrupo.grupo.idGrupo"))))
				.add(Restrictions.eq("vehiculoModeloFabrica.vehiculoModeloFabricaPK.idTipoComponente", tipoComponente.getIdTipoComponente()))
				.add(Restrictions.eq("vehiculo.chasis", vehiculo.getChasis()));
		List<Integer> listaIdsGrupos = criteria.list();
		return listarGruposPorIds(listaIdsGrupos);
	}

	@Override
	public List<Grupo> listarGruposPorVehiculoExtra(VehiculoExtra vehiculoExtra) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Imagen.class, "imagen")
				.createAlias("imagen.modeloFabrica", "modeloFabrica")
				.createAlias("modeloFabrica.listaModelo", "modelo")
				.createAlias("modelo.listaVehiculoExtra", "vehiculoExtra")
				.createAlias("imagen.subGrupo", "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.setProjection(Projections.projectionList().add(Projections.distinct(Projections.property("subGrupo.grupo.idGrupo"))))
				
				.add(Restrictions.eq("vehiculoExtra.idVehiculoExtra", vehiculoExtra.getIdVehiculoExtra()));
		
		List<Integer> listaIdsGrupos = criteria.list();
		
		return listarGruposPorIds(listaIdsGrupos);
	}

	@Override
	public List<Grupo> listarGruposPorIds(List<Integer> listaIdsGrupos) {
		if (listaIdsGrupos != null && listaIdsGrupos.size() > 0) {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Grupo.class, "grupo")
				.add(Restrictions.in("grupo.idGrupo", listaIdsGrupos))
				
				.addOrder(Order.asc("grupo.nombre"));
			return criteria.list();
		} else {
			return null;
		}
	}

	@Override
	public List<Grupo> listarPorNombre() {
		Criteria  criteria = sessionFactory.getCurrentSession().createCriteria(Grupo.class, "grupo")				
				.add(Restrictions.not(Restrictions.eq("estado",
						Constantes.ESTADO_ELIMINADO)))
				.addOrder(Order.asc("grupo.nombre"));
		return  criteria.list();
	}
}